package com.example.inventoryservice.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TryLockTest {

    private static final Lock lock = new ReentrantLock();

    public static void main(String[] args) {

        new Thread(() -> testTryLock("测试线程1", 1000)).start();
        try {
            Thread.sleep(500); // 让线程1先执行
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
//
//        new Thread(() -> testTryLock("测试线程2", 1000)).start();


//        new Thread(TryLockTest::run).start();
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                testTryLock("测试线程2");
//            }
//        }).start();
//        new Thread(() -> {
//            testTryLock("测试线程3");
//        }).start();


        TryLockTest example = new TryLockTest();

        Thread t1 = new Thread(example::performTask, "Thread-1");
        Thread t2 = new Thread(example::performTask, "Thread-2");

        t1.start();
        t2.start();
    }

    private static void testTryLock(String threadName, long timeout) {
        try {
            boolean tryLock = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
            System.out.println("TryLockTest.testTryLock" + threadName + "开始尝试获取锁" + tryLock);
            if (tryLock) {  // 尝试在timeout时间内获取锁
                try {
                    System.out.println("threadName = " + threadName + "___" + "获取到锁，开始执行任务");
                    Thread.sleep(1000); // 模拟任务执行
                } finally {
                    lock.unlock();
                    System.out.println("threadName = " + threadName + "___" + "释放锁");
                }
            } else {
                System.out.println(threadName + " 超时未获取到锁，执行其他逻辑（在规定的超时时间没有获取到锁）");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println(threadName + " 等待过程中被中断");
            throw new RuntimeException(e);
        }
    }

    /**
     * 测试无参tryLock方法
     *  tryLock() 立即返回 true 或 false，不会阻塞线程。
     *  必须在 finally 块中检查 acquired 状态，避免释放未持有的锁。
     *  适用于需要快速响应的场景，例如 UI 事件处理或实时系统。
     */
    private static void testTryLock(String threadName) {
        if (lock.tryLock()) {
            try {
                System.out.println("threadName = " + threadName + "___" + "获取到锁");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
                System.out.println("threadName = " + threadName + "___" + "释放锁");
            }
        } else {
            System.out.println(threadName + " 未获取到锁，执行其他逻辑");
        }
    }

    public void performTask() {
        try {
            // 尝试在2秒内获取锁
            if (lock.tryLock(2, TimeUnit.SECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 获取锁成功");
                    Thread.sleep(3000); // 模拟长时间任务
                } finally {
                    lock.unlock();
                    System.out.println(Thread.currentThread().getName() + " 释放锁");
                }
            } else {
                System.out.println(Thread.currentThread().getName() + " 在指定时间内未获取锁");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " 被中断");
        }
    }

    public void performTaskWithTimeout() throws InterruptedException {
        // 尝试获取锁，最多等待5秒
        if (lock.tryLock(5, java.util.concurrent.TimeUnit.SECONDS)) {
            try {
                // 成功获取锁
                System.out.println("线程 " + Thread.currentThread().getName() + " 获取到锁");
                // 执行任务
                Thread.sleep(2000);
            } finally {
                lock.unlock();
            }
        } else {
            // 超时未获取到锁
            System.out.println("线程 " + Thread.currentThread().getName() + " 超时未获取到锁");
        }
    }


}
